package com.xinqi.modules.databank.v2.util;

import com.xinqi.common.base.dto.QuestionBaseDTO;
import com.xinqi.common.base.dto.QuestionOptionsDTO;
import com.xinqi.common.base.enums.QuestionTypeEnum;
import com.xinqi.common.base.enums.YesNoNumberEnum;
import com.xinqi.common.base.utils.json.JSON;
import com.xinqi.modules.databank.dto.req.question.ResourceAnswerDTO;
import com.xinqi.modules.databank.dto.rsp.MarkRangeResultDTO;
import com.xinqi.modules.databank.dto.rsp.question.QuestionResultDTO;
import com.xinqi.modules.databank.v2.domain.CourseResourceInteractionLogEntity;
import org.apache.commons.collections4.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 资料库题目公共类
 * @author dzy
 */
public class QuestionUtil {

    private static String[] titles = new String[] {"A", "B", "C", "D", "E"};

    private static String[] rateVal = new String[] {"100-90", "90-80", "80-70", "70-60", "60-0"};

    /**
     * 转换学生答题记录
     */
    public static List<QuestionResultDTO> tranAnswer(List<QuestionResultDTO> questions, Boolean replyFlag, List<ResourceAnswerDTO> answers) {

        // 没有题目返回空List
        if (CollectionUtils.isEmpty(questions)) {
            return questions;
        }

        // 学生没有作答返回题目List
        if (CollectionUtils.isEmpty(answers)) {
            questions.forEach(item -> {
                item.setIsReply(YesNoNumberEnum.NO.getCode());
                // 没做答隐藏答案跟解析
                if (!replyFlag) {
                    initNoAnswerQuestion(item);
                }
            });
            return questions;
        } else {
            // 学生作答转换数据
            Map<Long, ResourceAnswerDTO> map = answers.stream().collect(Collectors.toMap(ResourceAnswerDTO::getQuestionId, ResourceAnswerDTO-> ResourceAnswerDTO));
            questions.forEach(item -> {
                // 判断试题是否已作答
                if (Objects.nonNull(map.get(item.getId()))) {
                    item.setIsReply(YesNoNumberEnum.YES.getCode());
                    // 学生选项赋值
                    ResourceAnswerDTO answer = map.get(item.getId());
                    item.getOptionList().forEach(oItem -> {
                        if (answer.getStudentAnswer().contains(oItem.getId())) {
                            oItem.setStudentCheck(YesNoNumberEnum.YES.getCode());
                        } else {
                            oItem.setStudentCheck(YesNoNumberEnum.NO.getCode());
                        }
                    });
                } else {
                    item.setIsReply(YesNoNumberEnum.NO.getCode());
                    // 没做答隐藏答案跟解析
                    if (!replyFlag) {
                        initNoAnswerQuestion(item);
                    }

                }
            });
        }
        return questions;
    }

    /**
     * 计算得分
     */
    public static CourseResourceInteractionLogEntity calcScore(CourseResourceInteractionLogEntity entity, List<QuestionBaseDTO> questions) {

        // 没有题目返得分为0
        if (CollectionUtils.isEmpty(questions)) {
            entity.setScore(new BigDecimal(0));
        }

        // 学生没有作答返回题目List
        if (CollectionUtils.isEmpty(entity.getAnswer())) {
            entity.setScore(new BigDecimal(0));
        } else {
            Map<Long, QuestionBaseDTO> map = questions.stream().collect(Collectors.toMap(QuestionBaseDTO::getId, QuestionBaseDTO-> QuestionBaseDTO));
            BigDecimal score = new BigDecimal(0);
            for (ResourceAnswerDTO answer : entity.getAnswer()) {
                if (Objects.nonNull(map.get(answer.getQuestionId()))) {
                    QuestionBaseDTO question = map.get(answer.getQuestionId());
                    answer.setIsReply(true);
                    answer.setScore(question.getScore());
                    if (checkAnswer(question, answer.getStudentAnswer())) {
                        answer.setIsRight(true);
                        answer.setStudentScore(question.getScore());
                        score = score.add(question.getScore());
                    } else {
                        answer.setIsRight(false);
                        answer.setStudentScore(new BigDecimal(0));
                    }
                } else {
                    answer.setIsReply(false);
                }
            }
            entity.setScore(score);
        }
        return entity;
    }

    /**
     * 校验是否答题
     */
    public static boolean checkAnswer(QuestionBaseDTO question, String answer) {
        // 校验判断题
        if (Objects.equals(QuestionTypeEnum.ANSWER_JUDGE.getCode(), question.getType())) {
            if (Objects.equals(question.getAnswer(), answer)) {
                return true;
            }
        }
        // 校验单选题
        else if (Objects.equals(QuestionTypeEnum.ANSWER_RADIO.getCode(), question.getType())) {
            if (Objects.equals(question.getAnswer(), answer)) {
                return true;
            }
        }
        // 校验多选题
        else if (Objects.equals(QuestionTypeEnum.ANSWER_MULTIPLE.getCode(), question.getType())) {
            if (Objects.equals(question.getAnswer(), answer)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取得分区间值
     * @return
     */
    public static List<MarkRangeResultDTO> generateMarkRange() {
        List<MarkRangeResultDTO> rangeList = new ArrayList<>();
        for (int i = 0; i < 5; i++){
            MarkRangeResultDTO result = new MarkRangeResultDTO();
            result.setTitle(titles[i]);
            result.setScoreRange(rateVal[i]);
            String[] rateSpace = rateVal[i].split("-");
            result.setMax(Integer.parseInt(rateSpace[0]));
            result.setMin(Integer.parseInt(rateSpace[1]));
            rangeList.add(result);
        }
        return  rangeList;
    }

    /**
     * 不返回 答案和解析
     * @param question
     */
    private static void initNoAnswerQuestion(QuestionResultDTO question) {
        question.setAnswer(null);
        question.setAnswerFile(null);
        question.setAnalysis(null);
        question.setAnalysisFile(null);
        question.getOptionList().forEach(item -> {
            item.setSelected(0);
        });
    }
    /**
     * 不返回 答案和解析
     * @param question
     */
    public static void initNoAnswerBaseQuestion(QuestionBaseDTO question) {
        question.setAnswer(null);
        question.setAnswerFile(null);
        question.setAnalysis(null);
        question.setAnalysisFile(null);
        question.getOptionList().forEach(item -> {
            item.setSelected(0);
        });
    }


    public static List<QuestionBaseDTO> tranOptionList(List<QuestionBaseDTO> questionBaseList) {
        questionBaseList.forEach(item -> {
            item.setOptionList(JSON.parseList(item.getOptions(), QuestionOptionsDTO.class));
        });
        return questionBaseList;
    }

}
